/*******************************************************************************
 * 版权：北京润尼尔网络科技有限公司，保留所有版权<br>
 * 版本：v1.0.0<br>
 * 文件：composite_object22.js<br>
 * 日期：2016年7月25日<br>
 * 作者: 杨顺强<br>
 * 功能： 定义组合对象<br>
 * 
 * 修改记录：<br>
 * 日期 描述 更新功能<br>
 ******************************************************************************/

;(function(){
	
	
	//定义名称空间
	var namespace ={};
	
	//创建名称空间：Rainier.Basic
	//根据Node.js后端还是web前端判断应该创建名称空间的空对象
	if((typeof(window) !== "undefined")){
		makeNamespace(window,"Rainier.Basic");
		namespace = window.Rainier.Basic;
	}else{
		require("../utils/nsutils.js").makeNamespace(exports,"Rainier.Basic");
		var ml_UUID				= require('../utils/uuid_utils.js');
		var ml_interface		= require("./interface.js");
		var ml_property			= require("./property.js");
		var ml_class			= require("./class.js");
		var ml_baseObject		= require("./base_object");
		namespace.UUID			= ml_UUID.UUID;
		namespace.Interface 	= ml_interface.Interface;
		namespace.Property  	= ml_property.Property;
		namespace.Class			= ml_class.Class;
		namespace.BaseObject 	= ml_baseObject.BaseObject;
	}  
	
	/**
	 * 类型名称：Rainier.Basic.g_InterfaceCompositeObject<br>
	 * 类型功能：组合接口定义<br>
	 * 接口函数：<br>
	 * addChild			添加子对象
	 * getChildren		获取子对象列表
	 * findChildById	通过ID号查找子对象
	 * removeChildById	根据ID号删除子对象
	 * clearChildren	清楚子对象列表
	 */
	
	namespace.g_InterfaceCompositeObject = new namespace.Interface(
			"CompositeObject",
			["addChild",
			 "getChildren",
			 "findChildById",
			 "removeChildById",
			 "clearChildren",
			 "eachChild",
			 "setParent",
			 "getParent",
			 "hasChildren"]
		);
	
	/**
	 * 类型名称：Rainier.Basic.CompositeObject<br>
	 * 类型功能：组合对象类定义<br>
	 * 接口函数：<br>
	 * addChild			添加子对象			<br>
	 * getChildren		获取子对象列表		<br>
	 * findChildById	通过ID号查找子对象	<br>
	 * removeChildById	根据ID号删除子对象	<br>
	 * clearChildren	清楚子对象列表		<br>
	 * 成员变量：<br>
	 * m_aChildren<br>
	 */
	 namespace.CompositeObject = namespace.BaseObject.extend({
	
		 NAME:"CompositeObject",
		 
		 init:function(){
			//初始化父类
			this._super();
			
		 	//成员变量定义：子对象列表
			this.m_aChildren = {};
			
			//成员变量定义：父对象
			this.m_objParent = null;
			
			//检测对象是否实现了借口中的所有函数
			this._checkInterface();
		 },
		 
		 /**
		 * 函数名称：Rainier.Basic.CompositeObject.setParent<br>
		 * 函数功能：设置父对象<br>
		 * 参数输入：objParent 父对象<br>
		 * 参数输入:isFireEvent:Boolean
		 * 函数返回：无<br>
		 * 异常信息：无<br>
		 */
		 setParent : function(objParent,isFireEvent){
			 this.m_objParent = objParent;
			 if(isFireEvent){
				 this.firePropertyChange(
						 namespace.CompositeObject.SC_S_EVENT_PARENT_CHANGED, 
						 null, 
						 objParent
				 );				 
			 }
		 },
		 
		 /**
		 * 函数名称：Rainier.Basic.CompositeObject.getParent<br>
		 * 函数功能：获取父对象实例<br>
		 * 函数返回：objParent 父对象<br>
		 * 异常信息：无<br>
		 */
		 getParent : function(){
		 	return this.m_objParent;
		 },
		 
		 /**
		 * 函数名称：Rainier.Basic.CompositeObject.addChildWithoutChangeParent<br>
		 * 函数功能：添加子对象<br>
		 * 参数输入：sObjId 		对象ID号<br>
		 * 参数输入：objInstance	对象实例<br>
		 * 参数输出：无<br>
		 * 函数返回：无<br>
		 * 异常信息：无<br>
		 */
		 addChildWithoutChangeParent : function(sObjId,objInstance){
			
			if(this.m_aChildren[sObjId]){
				return;
			}
			
			this.m_aChildren[sObjId] = objInstance;
			this.firePropertyChange(
					namespace.CompositeObject.SC_S_EVENT_ADD_CHILD, 
					null, 
					objInstance
			);
		},
		
		/**
		 * 函数名称：Rainier.Basic.CompositeObject.addChild<br>
		 * 函数功能：添加子对象<br>
		 * 参数输入：sObjId 		对象ID号<br>
		 * 参数输入：objInstance	对象实例<br>
		 * 参数输出：无<br>
		 * 函数返回：无<br>
		 * 异常信息：无<br>
		 */
		addChild : function(sObjId,objInstance){
			
			if(this.m_aChildren[sObjId]){
				return;
			}
			this.m_aChildren[sObjId] = objInstance;
			objInstance.setParent(this);
			this.firePropertyChange(
					namespace.CompositeObject.SC_S_EVENT_ADD_CHILD, 
					null, 
					objInstance
			);
		},

		/**
		 * 函数名称：Rainier.Basic.CompositeObject.addChild<br>
		 * 函数功能：添加子对象<br>
		 * 参数输入：sObjId 		对象ID号<br>
		 * 参数输入：objInstance	对象实例<br>
		 * 参数输出：无<br>
		 * 函数返回：无<br>
		 * 异常信息：无<br>
		 */
		removeChild : function(sObjId,objInstance){
			
			if(this.m_aChildren){
				// return;
			
			for(var key in this.m_aChildren){
				delete this.m_aChildren[key];
			}
			// this.m_aChildren[sObjId] = null;
			// objInstance.setParent(this);
			this.firePropertyChange(
					namespace.CompositeObject.SC_S_EVENT_DELETE_CHILD, 
					null, 
					objInstance
			);
			}
		},
		
		/**
		 * 函数名称：Rainier.Basic.CompositeObject.getChildren<br>
		 * 函数功能：获取子对象列表<br>
		 * 输入参数：objArray对象数组
		 * 函数返回：Array对象列表<br>
		 * 异常信息：无<br>
		 */
		getChildren : function(){
			var objArray = [];
			for ( var objKey in this.m_aChildren) {
				if(this.m_aChildren.hasOwnProperty(objKey)){
					objArray.push(this.m_aChildren[objKey]);
				}
			}
			return objArray;
		},
		
		/**
		 * 函数名称：Rainier.Basic.CompositeObject.hasChildren<br>
		 * 函数功能：是否还有孩子<br>
		 * 函数返回：bool<br>
		 * 异常信息：<br>
		 */
		hasChildren : function(){
			var oa = this.getChildren();
			return oa.length !== 0 ? true : false;
		},
		
		/**
		 * 函数名称：Rainier.Basic.CompositeObject.findChildById<br>
		 * 函数功能：通过ID号查找子对象<br>
		 * 参数输入：sObjId
		 * 函数返回：搜索到的对象<br>
		 * 异常信息：无<br>
		 */
		findChildById : function(sObjId){
			if(this.m_aChildren[sObjId]){
				return this.m_aChildren[sObjId];
			}
			return null;
		},
		
		/**
		 * 函数名称：Rainier.Basic.CompositeObject.removeChildById<br>
		 * 函数功能：通过ID号删除子对象<br>
		 * 参数输入：sObjId
		 * 函数返回：被删除的对象<br>
		 * 异常信息：无<br>
		 */
		removeChildById : function(sObjId){
			var obj = null;
			if(this.m_aChildren[sObjId]){
				//获取对象
				obj = this.m_aChildren[sObjId];
				//在数组中删除对象
				delete this.m_aChildren[sObjId];
				//广播删除事件
				this.firePropertyChange(
						namespace.CompositeObject.SC_S_EVENT_REMOVE_CHILD, 
						null, 
						obj
				);
				return obj;
			}			
			return obj;
		},
		
		/**
		 * 函数名称：Rainier.Basic.CompositeObject.clearChildren<br>
		 * 函数功能：清除子对象列表<br>
		 * 参数输入：sObjId
		 * 函数返回：被删除的对象<br>
		 * 异常信息：无<br>
		 */
		clearChildren : function(){
			var saKey = [];
			var index = 0;
			for(var sKey in this.m_aChildren){
				if(this.m_aChildren.hasOwnProperty(sKey)){
					saKey[index++] = sKey;
				}
			}
			for(var i=0; i<saKey.length; i++){
				this.removeChildById(saKey[i]);
			}
		},
		
		/**
		 * 函数名称：Rainier.Basic.CompositeObject.eachChild<br>
		 * 函数功能：遍历子对象列表<br>
		 * 参数输入：cbfunc 遍历回调函数<br>
		 * 异常信息：无<br>
		 */
		eachChild : function(cbfunc){
			for(var sKey in this.m_aChildren){
				if (this.m_aChildren.hasOwnProperty(sKey)){
					cbfunc(sKey,this.m_aChildren[sKey]);
				}
			}
		},
		
		/**
		 * 函数名称：Rainier.Basic.CompositeObject.getRoot<br>
		 * 函数功能：获取跟节点<br>
		 * 函数返回：Rainier.Basic.CompositeObject<br>
		 * 异常信息：<br>
		 */
		getRoot : function(){
			var root = null;
			var parent = null;
			if(this.parent === null){
				return this;
			}
			
			var parent = this.getParent();
			for(;;){
				if(parent.getParent()){
					parent = parent.getParent();
				}else{
					break;
				}
			}
			
			return parent;
		},
		
		/**
		 * 函数名称：_checkInterface 私有函数。<br>
		 * 函数功能：检测类对象是否实现了相应借口中相应的方法<br>
		 * 参数输入：无<br>
		 * 参数输出：无<br>
		 * 函数返回：无<br>
		 * 异常信息：无<br>
		 */
		_checkInterface:function(){
			var _this = this;
			namespace.Interface.checkImplements(_this,namespace.g_InterfaceCompositeObject);
		}
	 });
	 
	 /** 常量定义：Rainier.Basic.CompositeObject.SC_S_EVENT_ADD_CHILD*/
	namespace.CompositeObject.SC_S_EVENT_ADD_CHILD 		= "EVENT_ADD_CHILD";
	
	 /** 常量定义：Rainier.Basic.CompositeObject.SC_S_EVENT_DELETE_CHILD*/
	namespace.CompositeObject.SC_S_EVENT_DELETE_CHILD 		= "EVENT_DELETE_CHILD";

	/** 常量定义：Rainier.Basic.CompositeObject.SC_S_EVENT_REMOVE_CHILD*/
	namespace.CompositeObject.SC_S_EVENT_REMOVE_CHILD 	= "EVENT_REMOVE_CHILD";
	
	/** 常量定义：Rainier.Basic.CompositeObject.SC_S_EVENT_PARENT_CHANGED*/
	namespace.CompositeObject.SC_S_EVENT_PARENT_CHANGED	= "EVENT_PARENT_CHANGED";
	
	/**
	 * 函数名称：Rainier.Basic.CompositeObject.recursiveFindById<br>
	 * 函数功能：通过递归搜索子对象<br>
	 * 参数输入：objRoot	Rainier.Basic.CompositeObject实例对象<br>
	 * 参数输入：sObjId 	对象ID号
	 * 函数返回：搜索到的Rainier.Basic.CompositeObject实例对象<br>
	 * 异常信息：无<br>
	 */
	namespace.CompositeObject.recursiveFindById = function(objRoot,sObjId){
		var searched = null;
		namespace.CompositeObject.recursiveEach(objRoot,function(obj){
			if(obj.getUuid() === sObjId){
				searched = obj;
				return false;
			}
		});
		return searched;
	};
	
	/**
	 * 函数名称：Rainier.Basic.CompositeObject.recursiveEach<br>
	 * 函数功能：递归遍历所有子对象<br>
	 * 参数输入：objRoot	Rainier.Basic.classes.CompositeObject实例对象<br>
	 * 参数输入：cbfunc 	回调函数function(obj)
	 * 函数返回：搜索到的om.rainier.classes.CompositeObject实例对象<br>
	 * 异常信息：无<br>
	 */
	namespace.CompositeObject.recursiveEach = function(objRoot,cbfunc){
		if(cbfunc(objRoot) === false){
			return false;
		}
		var aChildren = objRoot.getChildren();
		for ( var key in aChildren) {
			if(aChildren[key]){
				if(namespace.CompositeObject.recursiveEach(aChildren[key],cbfunc) === false){
					break;
				}
			}
		}
	};
	
	
	/**
	 * 函数名称：Rainier.Basic.CompositeObject.reursiveRemoveChild<br>
	 * 函数功能：递归遍历所有子对象<br>
	 * 参数输入：objRoot	Rainier.Basic.CompositeObject实例对象<br>
	 * 参数输入：func:function(obj){};在删除对象前执行
	 * 函数返回：搜索到的om.rainier.classes.CompositeObject实例对象<br>
	 * 异常信息：无<br>
	 */
	namespace.CompositeObject.reursiveRemoveChild = function(objRoot,func){
		var objArray = objRoot.getChildren();
		for ( var key in objArray) {
			if(objArray[key].hasChildren()){
				namespace.CompositeObject.reursiveRemoveChild(objArray[key]);
			}else{
				if(objArray[key].getParent()){
					if(func){
						func(objArray[key]);						
					}
					objArray[key].getParent().removeChildById(objArray[key].getUuid());
				}
			}			
		}
		
		if(objRoot.getParent()){
			if(func){
				func(objRoot);				
			}
			objRoot.getParent().removeChildById(objRoot.getUuid());
		}
	};
	
	if (typeof exports !== "undefined") {
		exports.CompositeObject = namespace.CompositeObject;
	} 
})();